package com.wondream.myframework.app.utils;


import java.security.Key;
import java.security.MessageDigest;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.misc.BASE64Encoder;

public class HyTreeDesPKCPaddingUtil {
    public static final String KEY_ALGORITHM = "desede";
    public static final String CIPHER_ALGORITHM = "DESede/CBC/PKCS5Padding";
    public static final byte[] keyiv = new byte[]{8, 7, 6, 5, 4, 3, 2, 1};
    public static final String FIX_KEY_PUBLIC = "PUBLIC17495251443A9A6D90AF59A3A4FC5B871749525144";

    public HyTreeDesPKCPaddingUtil() {
    }

    public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        Key deskey = keyGenerator(new String(key));
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(1, deskey, ips);
        byte[] bOut = cipher.doFinal(data);

        for(int k = 0; k < bOut.length; ++k) {
            System.out.print(bOut[k] + " ");
        }

        System.out.println("");
        return bOut;
    }

    private static Key keyGenerator(String keyStr) throws Exception {
        byte[] input = HexString2Bytes(keyStr);
        DESedeKeySpec KeySpec = new DESedeKeySpec(input);
        SecretKeyFactory KeyFactory = SecretKeyFactory.getInstance("desede");
        return KeyFactory.generateSecret(KeySpec);
    }

    private static int parse(char c) {
        if (c >= 'a') {
            return c - 97 + 10 & 15;
        } else {
            return c >= 'A' ? c - 65 + 10 & 15 : c - 48 & 15;
        }
    }

    public static byte[] HexString2Bytes(String hexstr) {
        byte[] b = new byte[hexstr.length() / 2];
        int j = 0;

        for(int i = 0; i < b.length; ++i) {
            char c0 = hexstr.charAt(j++);
            char c1 = hexstr.charAt(j++);
            b[i] = (byte)(parse(c0) << 4 | parse(c1));
        }

        return b;
    }

    public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
        Key deskey = keyGenerator(new String(key));
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(2, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }

    public static byte[] getKeyBytes(String keyStr) throws Exception {
        if (null == keyStr || keyStr.length() < 1) {
            System.out.println("key为空");
        }

        MessageDigest alg = MessageDigest.getInstance("MD5");
        alg.update(keyStr.getBytes("UTF-8"));
        byte[] sourceBytes = alg.digest();
        byte[] result = new byte[24];

        for(int i = 0; i < 24; ++i) {
            result[i] = sourceBytes[i % 16];
        }

        return result;
    }

    public static void main(String[] args) throws Exception {
        byte[] key = "FC5B8717495251443A9A6D90AF59A3A4FC5B871749525144".getBytes();

        for(int i = 0; i < key.length; ++i) {
            System.out.printf("%x", key[i]);
        }

        System.out.println("");
        System.out.println(key.length);
        byte[] keyiv = new byte[]{8, 7, 6, 5, 4, 3, 2, 1};
        byte[] data = "a123".getBytes("UTF-8");
        System.out.println("data.length=" + data.length);
        System.out.println("CBC加密解密");
        byte[] str5 = des3EncodeCBC(key, keyiv, data);
        System.out.println((new BASE64Encoder()).encode(str5));
        byte[] str6 = des3DecodeCBC(key, keyiv, str5);
        System.out.println(new String(str6, "UTF-8"));
    }
}


